Joi数据验证

您所在的位置:网站首页 汉字头像 自定义 Joi数据验证

Joi数据验证

2023-11-05 04:06| 来源: 网络整理| 查看: 265

在编写api的时候通常都需要对参数进行校验,包括:

参数的类型、必填等; 字符串,是否可以为空、该符合什么规则等; 数字,最大值最小值是什么等等等等。

Joi 是 hapijs 自带的数据校验模块,它已经高度封装常用的校验功能。

1.安装及使用: //安装 npm install joi --save //引用 import Joi from 'joi' 2.基础使用

使用joi进行校验,首先要定义它的校验规则,也叫schema。

const schema = Joi.string()

上面就定义了一个校验字符串类型的规则,这个schema会有一个 validate方法,传入需要校验的值:

validate方法会返回一个对象,如果验证通过,就只会返回value属性,如果验证错误,就还有一个error对象,其中error对象的message描述了失败原因:

const schema = Joi.string() const result = schema.validate(1) console.log(result) // result: { value: 1, error: [Error [ValidationError]: "value" must be a string] { _original: 1, details: [ [Object] ] } }

因此,在此次介绍中,我将验证结果进行了封装,且下文将延续使用

/** * joi数据校验 * @param schema joi校验schema * @param data 需要验证的数据 */ function joiVerification(schema, data) { const {error, value} = schema.validate(data); if (error) throw new Error(JSON.stringify({code: 4003, message: `入参信息有误: ${error.message}`})); return value; } 3.schema基本校验方法 3.1 数据类型校验 .string()

检验字符串类型

let stringSchema = Joi.string(); joiVerification(stringSchema, 1); .number()

检验数字类型

let Schema = Joi.number(); joiVerification(Schema, 1); .array()

检验数组类型

let Schema = Joi.array(); joiVerification(Schema, []); .boolean()

检验布尔类型

let Schema = Joi.boolean(); joiVerification(Schema, true); .object()

检验对象类型

let Schema = Joi.object(); joiVerification(Schema, {}); .date()

检验时间类型

let Schema = Joi.date(); joiVerification(Schema, new Date("2022-01-01")); 3.2 常用schema校验 .required()

必选属性,如果需要此校验字段,需要将这个校验规则放到最后面。

let Schema = Joi.object({ name:Joi.string().required() }); joiVerification(Schema, {name:"long"}); .pattern()

正则校验

let Schema =Joi.string().pattern(/\d/ig); .optional()

可选字段,默认所有的字段都是可选的, 但是这个校验允许值为undefined但是不允许为null; 可以于.allow()一起使用

let info = { name:"long", age:null, sex:null }; let Schema = Joi.object({ name: Joi.string().required(), age: Joi.string().optional(), sex: Joi.string().optional().allow(null), }); joiVerification(Schema, info); //输出:"入参信息有误: \"sex\" must be a string" let info = { name:"long", age:undefined, sex:null }; let Schema = Joi.object({ name: Joi.string().required(), age: Joi.string().optional(), sex: Joi.string().optional().allow(null), }); joiVerification(Schema, info); //输出:成功通过校验 .allow(...values)

在校验条件外允许某些值通过

...values:一个或多个值 let Schema = Joi.object({ sex: Joi.string().optional().allow(null,"1234"), }); joiVerification(Schema, info); .invalid(...values)/别名:disallow,not

不允许以下值存在

values:可以是任何类型的禁止值,在应用任何其他规则之前将与验证值匹配. 如果第一个值为Joi.override, 将覆盖任何先前设置的值. let info = { sex:"100" }; let Schema = Joi.object({ sex: Joi.string().invalid("100").required(), }); joiVerification(Schema, info); //输出:"入参信息有误: \"sex\" contains an invalid value" .override()

any.allow()与、any.invalid()和一起使用的特殊值,any.valid()作为重置任何先前设置的值的第一个值。 个人认为,这个校验并没什么用;

Joi.valid(1).valid(Joi.override, 2); // Same as: Joi.valid(2); // Whereas: Joi.valid(1).valid(2); // Is the same as: Joi.valid(1, 2); .default([value])

默认值

【value】:只允许有一个值,但是取值允许为 字符串、数字、对象等 使用签名返回默认值的函数,function(parent, helpers)其中: parent- 包含正在验证的值的对象的克隆。请注意,由于指定parent参数会执行克隆,因此如果您不使用格式参数,请不要声明它们。 helpers- 与 中描述的相同any.custom()。 let Schema = Joi.object({ sex: Joi.string().optional().default("1").allow(null,"1234"), }); joiVerification(Schema, info); //下面是官方的函数例子, const generateUsername = (parent, helpers) => { return parent.firstname.toLowerCase() + '-' + parent.lastname.toLowerCase(); }; generateUsername.description = 'generated username'; const schema = Joi.object({ username: Joi.string().default(generateUsername), firstname: Joi.string(), lastname: Joi.string(), created: Joi.date().default(Date.now), status: Joi.string().default('registered') }); .valid(...values)/别名:equal

允许的枚举值

let info = { sex:"1" }; let Schema = Joi.object({ sex: Joi.string().valid("0","1").required(), }); joiVerification(Schema, info); //同样效果,逻辑相同,不要问为什么不能传array了,运算符...了解一下 let info = { sex:"1" }; let sexEnum = ["0","1"]; let Schema = Joi.object({ sex: Joi.string().valid(...sexEnum).required(), }); joiVerification(Schema, info); .when([condition],options)

官方解释:添加在验证期间评估的条件并在将架构应用于值之前对其进行修改 其实就是:相当于条件判断

condition:属性名称 options:对象属性,判断条件及处理方案 is- 表示为joi模式的条件。任何不是joi模式的东西都将使用Joi.compile进行转换。默认情况下,is条件架构允许undefined值。用于.required()覆盖。例如,用于is: Joi.number().required()保证joi引用存在并且是一个数字。 not- 的否定版本is(then并且otherwise具有相反的角色)。 then- 如果条件为真,则要使用的joi模式。 otherwise- 如果条件为假,则使用joi模式。 switch-{ is, then }根据condition. 数组中的最后一项也可能包含otherwise. break- 如果规则导致匹配then,otherwise则停止处理所有其他条件。switch

一般情况,options包含is、then、otherwise即可,甚至,otherwise都可以不要

//如果email存在时,判断email是否符合邮箱格式,符合,则判断name字段必填,都则,name属性可以选填 let info = { email: "[email protected]", name:"long" }; let Schema = Joi.object({ email: Joi.string(), name: Joi.string().when("email",{is:Joi.string().email(),then:Joi.string().required()}) }); joiVerification(Schema, info); 3.3 joi封装的实用校验规则 .min(limit)

指定数组中的最小项目数、数字最小值、字符串最小长度

limit- 允许的最小数组项数或引用。 let info = { email: "[email protected]", age:16, address:["郑州","衢州","广州"] }; let Schema = Joi.object({ email: Joi.string().min(1), age: Joi.number().min(15), address:Joi.number().min(2) }); joiVerification(Schema, info); .max(limit)

指定数组中的最大项目数、数字最大值、字符串最大长度

limit- 允许的最小数组项数或引用。 let info = { email: "[email protected]", age:16, address:["郑州","衢州","广州"] }; let Schema = Joi.object({ email: Joi.string().min(1).max(18), age: Joi.number().min(15).max(100), address:Joi.number().min(2).max(15) }); joiVerification(Schema, info); .length(limit,[encoding])

指定所需的确切字符串长度

limit- 所需的字符串长度或参考。 encoding- 如果指定,则使用提供的编码以字节为单位计算字符串长度。 let info = { mobile: "13027711111" }; let Schema = Joi.object({ mobile: Joi.string().length(11) }); joiVerification(Schema, info); .email([oprions])

要求字符串值是有效的电子邮件地址,一般options不用传入任何信息

options- 可选设置: allowFullyQualified- 如果,允许以字符true结尾的域。.默认为false. allowUnicode- 如果true,则允许使用 Unicode 字符。默认为true. ignoreLength- 如果true,忽略无效的电子邮件长度错误。默认为false. minDomainSegments- 域所需的段数。默认设置不包括单个分段域,例如example@io哪个是有效的电子邮件但非常不常见。默认为2. maxDomainSegments- 允许的域段的最大数量。默认为无限制。 multiple- 如果true, 允许在单个字符串中使用多个电子邮件地址,由, 或separator字符分隔。默认为false. separator- 当multipleis时true,覆盖默认,分隔符。字符串可以是单个字符或多个分隔符。默认为','. tlds- TLD(顶级域)验证选项。默认情况下,TLD 必须是IANA 注册表中列出的有效名称。要禁用验证,请设置tlds为false。要自定义 TLD 的验证方式,请设置以下选项之一: allow- 之一: true使用已注册 TLD 的 IANA 列表。这是默认值。 false允许deny列表中未列出的任何 TLD(如果存在)。 允许的 TLD的一个Set或数组。不能与 一起使用deny。 deny- 之一: 一个Set或一组被禁止的 TLD。不能与自定义allow 列表一起使用。 let info = { email: "[email protected]" }; let Schema = Joi.object({ email: Joi.string().email() }); joiVerification(Schema, info); .uri([options])

校验uri是否符合规范

options- 可选设置: scheme- 指定一个或多个可接受的方案,应该只包括方案名称。可以是数组或字符串(字符串会自动转义以在正则表达式中使用)。 allowRelative- 允许相对 URI。默认为false. relativeOnly- 仅限制相对 URI。默认为false. allowQuerySquareBrackets- 允许在查询字符串中使用未编码的方括号。这不符合 RFC 3986 标准,但现在查询字符串abc[]=123&abc[]=456非常普遍。默认为false. domain- 使用中指定的选项验证域组件string.domain()。 let info = { callbackUri: "https://www.baidu.com" }; let Schema = Joi.object({ callbackUri: Joi.string().uri({scheme:["https"]}) }); joiVerification(Schema, info); truncate([enabled])

指定是否string.max()应将限制用作截断

enabled- 可选参数默认true允许您通过提供虚假值来重置截断的行为。 let info = { name: "long1234" }; let Schema = Joi.object({ name: Joi.string().max(4).truncate() }); let value = joiVerification(Schema, info); console.log(value); //输出:long 官方文档

joi.dev/api/?v=17.6…



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3